package com.naive.imperative.view;

import java.util.IdentityHashMap;
import java.util.Map;

import com.naive.imperative.program.Operation;
import com.naive.imperative.program.OperationBlock;

public class RootRenderer extends BlockRenderer {
	private Map<OperationRenderer,OperationRenderer> childToParent = new IdentityHashMap<OperationRenderer, OperationRenderer>();
	private Map<Operation,OperationRenderer> opToRenderer = new IdentityHashMap<Operation, OperationRenderer>();
	
	public RootRenderer(OperationBlock block) {
		super(block);
	}
	
	protected void invalidateUpwards(OperationRenderer r) {
		OperationRenderer parent = r;
		while (parent != null) {
			parent.setNeedsLayout();
			parent = getParent(parent);
		}
	}
	
	public OperationRenderer getParent(OperationRenderer r) {
		return childToParent.get(r);
	}
	
	private void register(OperationRenderer r) {
		opToRenderer.put(r.getOperation(), r);
		for(OperationRenderer child: r.getRenderers()) {
			childToParent.put(child, r);
			register(child);
		}
	}
	
	private void unregister(OperationRenderer r) {
		for(OperationRenderer child: r.getRenderers()) {
			childToParent.remove(child);
			opToRenderer.remove(child.getOperation());
			unregister(child);
		}
	}
	
	public OperationRenderer locate(Operation o) {
		return opToRenderer.get(o);
	}
	
	public void registerReplace(Operation childOperation, OperationRenderer r) {
		unregister(locate(childOperation));
		register(r);
		invalidateUpwards(r);
	}
}
